package top.vanchor.myblog2back.controller.admin;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import top.vanchor.myblog2back.entity.BackAdmin;
import top.vanchor.myblog2back.entity.BackAuthGroup;
import top.vanchor.myblog2back.service.IBackAdminService;
import top.vanchor.myblog2back.service.IBackAuthGroupRuleService;
import top.vanchor.myblog2back.service.IBackAuthGroupService;
import top.vanchor.myblog2back.service.IBackAuthRuleService;
import top.vanchor.myblog2back.utils.JWTUtils;
import top.vanchor.myblog2back.utils.JwtInterceptor;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author Ding
 * @since 2022-01-27
 */
@RestController
@RequestMapping("/admin/adminGroup")
public class BackAuthGroupController {

    @Resource
    private IBackAuthGroupService service;
    @Resource
    private IBackAdminService adminService;
    @Resource
    private IBackAuthGroupRuleService groupRuleService;
    @Resource
    private IBackAuthRuleService ruleService;

    /**
     * 获取角色下拉框
     *
     * @return json
     */
    @ApiOperation("获取角色")
    @ResponseBody
    @GetMapping("/getRoles")
    public JSONObject getRoles() {
        JSONObject jsonObject = new JSONObject();
        JSONObject jsonTemp = new JSONObject();
        List<BackAuthGroup> groups = new ArrayList<>();
        try {
            groups = service.getRoles();
            jsonObject.put("code", 200);
            jsonObject.put("msg", "获取成功");
            jsonTemp.put("list", groups);
            jsonObject.put("data", jsonTemp);
        } catch (Exception e) {
            e.printStackTrace();
            jsonObject.put("code", 500);
            jsonObject.put("msg", "服务器异常，获取失败");
        }
        return jsonObject;
    }

    /**
     * 获取角色列表
     *
     * @param pageNo   页码
     * @param pageSize 每页数
     * @param title    名称
     * @return json
     */
    @ApiOperation("获取角色列表")
    @ResponseBody
    @GetMapping("/getList")
    public JSONObject getList(
            @RequestParam("pageNo") Integer pageNo,
            @RequestParam("pageSize") Integer pageSize,
            @RequestParam(name = "title", defaultValue = "") String title) {
        JSONObject jsonObject = new JSONObject();
        JSONObject jsonTemp = new JSONObject();
        Integer aId = Integer.parseInt(Objects.requireNonNull(JWTUtils.getUserId(JwtInterceptor.getTokenInfo())));
        Integer groupId = adminService.getById(aId).getAGroupId();
        //根据角色id获取角色权限
        BackAuthGroup group = service.getById(groupId);
        try {
            if ("SUPER_ADMIN".equals(group.getRole())) {
                //最高权限，必然获取
                PageInfo<BackAuthGroup> list = service.getList(pageNo, pageSize, title);
                jsonObject.put("code", 200);
                jsonObject.put("msg", "获取成功");
                jsonTemp.put("list", list.getList());
                jsonTemp.put("total", list.getTotal());
                jsonObject.put("data", jsonTemp);
            } else {
                //普通权限，必然不能拥有系统管理的权限-防止篡位
                jsonObject.put("code", 310);
                jsonObject.put("msg", "无权访问，您没有权限");
            }
        } catch (Exception e) {
            e.printStackTrace();
            jsonObject.put("code", 500);
            jsonObject.put("msg", "服务器异常，获取失败");
        }
        return jsonObject;
    }

    @ApiOperation("添加、修改角色")
    @PostMapping("/doEdit")
    @ResponseBody
    public JSONObject doEdit(@RequestBody BackAuthGroup bean) {
        JSONObject jsonObject = new JSONObject();
        int editNum = 0;
        try {
            boolean isSuperAdmin = "SUPER_ADMIN".equals(service.getGroupById(adminService.getById(Integer.parseInt(Objects.requireNonNull(JWTUtils.getUserId(JwtInterceptor.getTokenInfo())))).getAGroupId()).getRole());
            //防止postman等应用于一般管理员入侵
            if (!isSuperAdmin) {
                jsonObject.put("code", 250);
                jsonObject.put("msg", "操作失败，该操作需要最高权限");
                return jsonObject;
            }
            /*
              添加要求
              各角色标题唯一
             */
            if (bean.getGroupId() == null) {
                //超级管理员必须唯一，超级管理员不可以拥有增删改查的操作
                if ("SUPER_ADMIN".equals(bean.getRole())) {
                    jsonObject.put("code", 251);
                    jsonObject.put("msg", "不可添加超级管理员");
                    return jsonObject;
                }
                if (service.getByTitle(bean.getTitle()) > 0) {
                    //存在该名称的角色
                    jsonObject.put("code", 530);
                    jsonObject.put("msg", "该角色名称已存在");
                    return jsonObject;
                }
            }
            /*
              编辑要求
              各角色标题唯一
             */
            if (bean.getGroupId() != null) {
                //超级管理员不可以拥有增删改查的操作
                BackAuthGroup beforeEditBean = service.getGroupById(bean.getGroupId());
                if ("SUPER_ADMIN".equals(beforeEditBean.getRole())) {
                    jsonObject.put("code", 251);
                    jsonObject.put("msg", "不可编辑超级管理员");
                    return jsonObject;
                }
                if (service.getByTitle(bean.getTitle()) > 0 && !beforeEditBean.getTitle().equals(bean.getTitle())) {
                    //存在该名称的角色
                    jsonObject.put("code", 530);
                    jsonObject.put("msg", "该角色名称已存在");
                    return jsonObject;
                }
            }
            /*
              没有被拦截
              走添加/编辑方法
             */
            boolean isAdd = bean.getGroupId() == null;
            editNum += service.doEdit(bean);
            if (editNum > 0) {
                jsonObject.put("msg", isAdd ? "添加成功" : "编辑成功");
            } else {
                jsonObject.put("code", 510);
                jsonObject.put("msg", "操作失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            jsonObject.put("code", 500);
            jsonObject.put("msg", "服务器异常，操作失败");
        }
        return jsonObject;
    }

    /**
     * 删除角色
     *
     * @param data json类型的ids-需要处理成数组和list
     * @return json
     */
    @ApiOperation("删除角色")
    @ResponseBody
    @PostMapping("/doDelete")
    public JSONObject doDelete(@RequestBody JSONObject data) {
        JSONObject jsonObject = new JSONObject();
        //处理前端数据
        String[] idsStr = String.valueOf(data.get("ids")).split(",");
        List<Integer> ids = new ArrayList<>();
        for (String s : idsStr) {
            ids.add(Integer.parseInt(s));
        }
        //遍历，确认其身份不是SUPER_ADMIN，否则return
        int beforeIdsSize = ids.size();
        for (int i = 0; i < ids.size(); i++) {
            if ("SUPER_ADMIN".equals(service.getGroupById(ids.get(i)).getRole())) {
                ids.remove(i--);
            }
        }
        if (ids.size() < beforeIdsSize) {
            jsonObject.put("code", 500);
            jsonObject.put("msg", "选择中含有" + (beforeIdsSize - ids.size()) + "个超级管理员，请取消相应的勾选");
            return jsonObject;
        }
        //初始化
        int delNum = 0;
        //执行
        try {
            delNum += service.doDeleteBy(ids);
            if (delNum >= ids.size()) {
                jsonObject.put("code", 200);
                jsonObject.put("msg", "已删除" + delNum + "个管理员");
            } else if (delNum > 0) {
                jsonObject.put("code", 200);
                jsonObject.put("msg", "部分删除成功，" + delNum + "/" + ids.size());
            } else {
                jsonObject.put("code", 500);
                jsonObject.put("msg", "服务器异常，删除失败");
            }
        } catch (Exception e) {
            jsonObject.put("code", 500);
            jsonObject.put("msg", "服务器异常，操作失败");
        }
        return jsonObject;
    }

    /**
     * 禁用 or 启用 角色
     *
     * @param bean pojo实体类
     * @return json
     */
    @ApiOperation("禁用/启用管理员")
    @PostMapping("/changeStatus")
    @ResponseBody
    public JSONObject changeStatus(@RequestBody BackAuthGroup bean) {
        JSONObject jsonObject = new JSONObject();
        if (service.doEdit(bean) > 0) {
            jsonObject.put("code", 200);
            jsonObject.put("msg", bean.getStatus() == 1 ? "启用成功！" : "禁用成功！");
        } else {
            jsonObject.put("code", 500);
            jsonObject.put("msg", "处理失败！");
        }
        return jsonObject;
    }

    @ApiOperation("根据角色id获取权限ids")
    @PostMapping("/getRuleIdsById")
    @ResponseBody
    public JSONObject getRuleIdsById(@RequestBody JSONObject data) {
        JSONObject jsonObject = new JSONObject();
        JSONObject jsonTemp = new JSONObject();
        Integer groupId = Integer.parseInt(String.valueOf(data.get("id")));
        List<Integer> ruleIds = new ArrayList<>();
        try {
            ruleIds = groupRuleService.getRuleIdsByGroupId(groupId);
            jsonObject.put("code", 200);
            jsonObject.put("msg", "获取成功");
            jsonTemp.put("list", ruleIds);
            jsonObject.put("data", jsonTemp);
        } catch (Exception e) {
            e.printStackTrace();
            jsonObject.put("code", 500);
            jsonObject.put("msg", "服务器异常，获取失败！");
        }
        return jsonObject;
    }

    @ApiOperation("为角色分配权限")
    @PostMapping("/doRulesEdit")
    @ResponseBody
    public JSONObject doRulesEdit(@RequestBody JSONObject data) {
        JSONObject jsonObject = new JSONObject();
        Integer groupId = Integer.parseInt(String.valueOf(data.get("groupId")));
        if ("SUPER_ADMIN".equals(service.getById(groupId).getRole())) {
            jsonObject.put("code", 250);
            jsonObject.put("msg", "你不能修改超级管理员的权限！");
            return jsonObject;
        }
        List<Integer> ruleIds = new ArrayList<>();
        try {
            List<Integer> temp = new ArrayList<>();
            ruleIds = (List<Integer>) data.get("rules");
            //前端编辑权限：当子节点不全时，无法获取父节点，因此查所有再去重
            for (Integer ruleId : ruleIds) {
                List<Integer> list = ruleService.getAllTopRules(ruleId);
                for (Integer integer : list) {
                    temp.add(integer);
                }
            }
            //这样会获得一个非常冗杂的ids，去重
            ruleIds = temp.stream().distinct().collect(Collectors.toList());

            if (ruleIds.size() != 0 && ruleService.checkIsForbidden(ruleIds)) {
                //这里面存在不被允许选择的id
                jsonObject.put("code", 251);
                jsonObject.put("msg", "存在普通管理员不被允许的权限！");
                return jsonObject;
            }
            //正常添加
            int changesNum = 0;
            changesNum += groupRuleService.doRulesEdit(groupId, ruleIds);
            jsonObject.put("code", 200);
            jsonObject.put("msg", "分配成功！");
        } catch (Exception e) {
            e.printStackTrace();
            jsonObject.put("code", 500);
            jsonObject.put("msg", "服务器异常，请求失败！");
        }
        return jsonObject;
    }
}
